/**
 * @author kidy
 */
if (typeof DBHelper=='undefined') {
    DBHelper = {};
}
if(!DBHelper.get){
    DBHelper.get = function(url,data,callback,timeout){
        $.ajax({
            type:'GET',
            url:url,
            cache:false,
            timeout:timeout?timeout:null,
            data:$.param(data), 
            success:function(data){
                callback(data);
            },
            error:function(){
                callback("error");
            }
        });
    };
}
var msStyleBoxDataManager = function(){
	this.registerMap = {};//cache stylebox
	this.registerParentMap={};//cache parent for update grid
	this.profile={
		pullTime:1,
        flashRange: '1d',
        getQuoteDataURL:(version.rtq||"../") + "invoke/barQuote",
        getHistoryDataURL:(version.rtq||"../") + "invoke/barHistoryData",
        dataPoint:{'1d':'dChg%','1w':'dpd005','1m':'dpd007','3m':'dpd009','1y':'dpd00d','3y':'dpd00f'},
        timeout:10
	};
	this.lockQuote=false;
	this.tagHistory=false;//only to get one time
	this.intervalObj=null;
	this.datas = {};//cache the data
	this.cacheColorData={};
	this.loadData=1;//1: not load ,2 loading, 3 loaded
	this.checkTickerData=1;//1: not check ,2 checking, 3 checked
}

msStyleBoxDataManager.prototype = {
	setInterval:function(arg){
        var self=this;
        if(this.intervalObj==null){
            this.getQuoteFromdCom(arg,true);
            this.intervalObj= window.setInterval(function(){self.getQuoteFromdCom(arg);},
                this.profile.pullTime*60*1000);
        }
    },
	getQuoteFromdCom:function(arg,first){
        if(this.lockQuote) return;
        this.lockQuote = true;
        var self=this;
        var ticker = {ticker:arg["ticker"].join(",")};
        DBHelper.get(this.profile.getQuoteDataURL,ticker,function(data){
            self.lockQuote = false;
            if(data!=null&&$.trim(data)!=""){ 
                var dataObj=$.evalJSON(data),datapoint=self.profile.dataPoint[self.profile.flashRange];
                var ticker=null,needUpdateData={},tickerid=null,tickerData={},dataitem=null,odataitem=null;
                for(var i=0,l=dataObj.length;i<l;i++){
                    needUpdateData={};
                    ticker = dataObj[i],tickerid=ticker.ticker.substr(1,4),tickerData=ticker.data;
                    dataitem=tickerData[datapoint],odataitem=self.datas[tickerid][datapoint];
                    if(first||(typeof dataitem!='undefined'&&dataitem!=odataitem)){
                        needUpdateData[datapoint] = {"value":isNaN(dataitem)? 0.00 : parseFloat(dataitem),"ovalue":isNaN(odataitem)? 0.00 : parseFloat(odataitem)};
                        $.extend(true,self.datas[tickerid],tickerData);
                        if(!first){
	                        self.updateData(tickerid,needUpdateData);
	                    }
                    }
                }
                if(first){
	            	self.updateColor(null,self.profile.flashRange,true);//true stand for only updating this range
	                self.bindDataGrid(self.profile.flashRange,true);//true stand for only updating this range
	            }
            }
        },this.profile.timeout*1000);
    },
	getHistoryData:function(arg,callback){
		if(this.tagHistory) return;
        this.tagHistory = true;
		var self=this;
		var ticker = {ticker:arg["ticker"].join(",")};
		DBHelper.get(this.profile.getHistoryDataURL,ticker,function(data){
            if(data!=null&&$.trim(data)!=""){ 
                var dataObj=$.evalJSON(data),datapoint=self.profile.dataPoint[self.profile.flashRange];
                var ticker=null,tickerid=null,tickerData={};
                for(var i=0,l=dataObj.length;i<l;i++){
                    ticker = dataObj[i],tickerid=ticker.ticker.substr(1,4),tickerData=ticker.data;
                    if(!self.datas[tickerid]){
                    	self.datas[tickerid]={};
                    }
                    $.extend(true,self.datas[tickerid],tickerData);
                }
            	self.updateColor(null,self.profile.flashRange,false);
                self.bindDataGrid(self.profile.flashRange);
                if(typeof callback=="function"){
                	callback();
                }
            }
        },this.profile.timeout*1000);
	},
	updateColor:function(parent,dataRange,only){
		if(typeof parent!="undefined"&&parent!=null) {
			if(this.registerMap[parent]){
				this.refreshStyleBox(parent,dataRange);
			}
		}else{
			var parent=null;
			for(var parentid in this.registerMap){
				parent=this.registerParentMap[parentid];
				if(!parent) continue;
				for(var range in this.profile.dataPoint){
					if(only&&range==dataRange){
						this.refreshStyleBox(parentid,range,true);
					}else if(!only&&range!=dataRange){
						this.refreshStyleBox(parentid,range,false);
					}
				}
			}
		}
	},
	getData:function(dataRange){
		return this._calculateReturn(dataRange);
	},
	bindDataGrid:function(range,only){
		var parent=null,childrange=null;
		for(var id in this.registerParentMap){
			parent=this.registerParentMap[id];
			if(!parent) continue;
			childrange=parent.getRange();
			if(only){
				if(childrange==range){
					parent.bindGrid();
				}
			}else{
				if(childrange!=range){
					parent.bindGrid();
				}
			}
		}
	},
	updateData:function(tickerid,needUpdateData){
		for(var id in this.registerParentMap){
			this.registerParentMap[id].updateData(tickerid,needUpdateData);
		}
	},
	_calculateReturn: function(range){
		if (this.cacheColorData[range] &&!$.isEmptyObject(this.cacheColorData[range].data) && range != this.profile.flashRange) {
			return this.cacheColorData[range];
		}
		var boundary = 0,gKey=null,data = null, d={},ind = {},dataPoint = this.profile.dataPoint[range];
		for(var key in this.datas){
			data=this.datas[key][dataPoint];
			d[key] = isNaN(data)? 0.00 : parseFloat(data);
			boundary = Math.max(Math.abs(d[key]),boundary);
		}
		this.cacheColorData[range]={
			boundary: boundary,
			data: d
		};
		return this.cacheColorData[range];
	},
	refreshStyleBox:function(parent,dataRange,showRange){
		if(typeof dataRange=='undefined'||dataRange==null){
			for(var datapoint in this.registerMap[parent]){
				this.registerMap[parent][datapoint].updateStyleBox(this._calculateReturn(datapoint));
			}
		}else{
			this.registerMap[parent][dataRange].updateStyleBox(this._calculateReturn(dataRange));
		}
		if(showRange){
			this.showRange(parent,dataRange);
		}
	},
	showRange:function(parent,dataRange){
		this.registerMap[parent][dataRange].showRange();
	},
	showMain:function(parent){
		if(!this.registerMap[parent]) return;
		if(this.registerMap[parent][this.profile.flashRange]){
			this.registerMap[parent][this.profile.flashRange].showRange();
		}
	},
	register: function(parent,type,obj){
		if(!this.registerMap[parent]) this.registerMap[parent]={};
		this.registerMap[parent][type]=obj;
	},
	unregister:function(parent){
		delete this.registerMap[parent];
	},
	registerGrid:function(parent,grid){
		this.registerParentMap[parent]=grid;
	},
	unregisterGrid:function(parent){
		delete this.registerParentMap[parent];
	}
}

var QS_MSStyleBoxDataManager = new msStyleBoxDataManager();

var QS_MSStyleBox = function(container, profile, colorGroup){
	this.profile = {
		width: 100,
		showRtn: false,
		clickable: false,
		showHeader:false,
		label:"",
		scope:null,
		decimal:2,
		showRangeTitle:true
	}
	this.type=profile.type||"1d";
	this.category=profile.category||"";
	this.callback = {};

	this.minWidth = 100;
	this.el = null;
    /**    this.HTML = '<div class="qs_msstylebox">' +
     //        '<div class="large row">' +
     //        '<div class="value cell"></div>' +
     //        '<div class="core cell"></div>' +
     //        '<div class="growth cell"></div>' +
     //        '</div>' +
     //
     //        '<div class="mid row">' +
     //        '<div class="value cell"></div>' +
     //        '<div class="core cell"></div>' +
     //        '<div class="growth cell"></div>' +
     //        '</div>' +
     //
     //        '<div class="small row">' +
     //        '<div class="value cell"></div>' +
     //        '<div class="core cell"></div>' +
     //        '<div class="growth cell"></div>' +
     //        '</div>' +
     //    '</div>';*/

    this.colorGroupObj = colorGroup;
	
	this.HTML ='<div class="qs_msstylebox">'+ 
		'<table cellpadding="0" cellspacing="0" class ="msstylebox">' +
			'<tbody>' +
				'<tr>' +
		            '<td key="MLVL" class="large value" index=1></td>' +
		            '<td key="MLCR" class="large core" index=2></td>' +
		            '<td key="MLGR" class="large growth" index=3></td>' +
	            '</tr>' +
				'<tr>' +
		            '<td key="MMVL" class="mid value" index=4></td>' +
		            '<td key="MMCR" class="mid core" index=5></td>' +
		            '<td key="MMGR" class="mid growth" index=6></td>' +
	            '</tr>' +
				'<tr>' +
		            '<td key="MSVL" class="small value" index=7></td>' +
		            '<td key="MSCR" class="small core" index=8></td>' +
		            '<td key="MSGR" class="small growth" index=9></td>' +
	            '</tr>' +
		    '</tbody>' +
		'</table>'+
	'</div>'
	
	this.init(container, profile);
}

QS_MSStyleBox.prototype = {
    init: function(container, profile){
		this.el = $(this.HTML);
		this.container = container;
		this.el.appendTo(this.container);
		$.extend(true, this.profile, profile);
		$.extend(true, this.callback, profile["callback"]||{});
		this._bindEvent();
		if (this.profile.showHeader) {
            this.el.append('<table class="header-right" style="float:left;width:25px"><tbody><tr><td>Lrg</td></tr><tr><td>Mid</td></tr><tr><td>Sml</td></tr></tbody></table>');
			this.el.append('<table class="header-bottom" style="float:left;height:20px;clear:both;"><tbody><tr><td>Val</td><td>Cor</td><td>Gro</td></tr></tbody></table>');
        }
		if (this.profile.showRangeTitle) {
			this.el.append('<div class="range"><label>' + this.profile.label + '</label></div>');
		}
		this.reSize();
	},
    _bindEvent: function(){
		var self = this;
		this.el.bind('mouseover', function(){
			self.showRange();
			if(self.profile.clickable){
				self.el.css({"cursor":"pointer"});
			}else if(self.profile.showRtn){
				self.el.css({"cursor":"default"});
			}
		});
		this.el.bind('mouseout', function(){
			self.showMain();
			if(self.profile.clickable){
				self.el.css({"cursor":"default"});
			}
		});
		if(this.profile.clickable){
			this.el.bind('click', function(e){
				if(e.target.tagName.toUpperCase()=="TD"){
					self._click(e,$(e.target).attr("index"));
				}
			});
		}
	},
	_click:function(e,index){
		if (this.callback["onClick"]) {
			this.callback["onClick"]["callee"].apply(this.callback["onClick"]["caller"], [e, index]);
		}
	},
	updateStyleBox: function(data){//{"boundary":234,data:{},colorIdx:{}}
		var r = data["boundary"];
		if (r && !this.profile.scope) {
			this.profile.scope = r;
		}
		var $td=null,colors = this.colorGroupObj.getColors(),value=null;
		for (var key in data["data"]) {
			value=data["data"][key];
			$td = this.el.find('td[key="' + key + '"]');
			if (this.profile.showRtn){
				$td.html(this._toDecimal(value) + "%");
			}
			$td.css('background-color', colors[this._calcColorScope(value,this.profile.scope)]);
		}
	},
	_calcColorScope:function(value,boundary){
		//green 0 -> red 6
		/*
		var unit= boundary*2/5,scope=Math.floor((value+boundary)/unit);
		return scope >=5?0:scope <=0?6:5-scope;
		*/
		var colorindex="3",boundaryrange=boundary/2;
        switch(this.type){
            case "1d":
            case "1w":
                if(value<boundary*-1){
                    colorindex="6";
                }else if(value>=boundary*-1&&value<-0.5){
                    colorindex="5";
                }else if(value>=-0.5&&value<0.0){
                    colorindex="4";
                }else if(value==0.0){
                    colorindex="3";
                }else if(value>0.0&&value<=0.5){
                    colorindex="2";
                }else if(value>0.5&&value<=boundary){
                    colorindex="1";
                }else if(value>boundary){
                    colorindex="0";
                }
                break;
                //'1d': 'dChg%', '1w': 'dpd005', '1m': 'dpd007', '3m': 'dpd009', '1y': 'dpd00d', '3y': 'dpd00f'},
            case "1m":
            case "3m":
            case "1y":
            case "3y":
                if(value<boundary*-1){
                    colorindex="6";
                }else if(value>=boundary*-1&&value<boundaryrange*-1){
                    colorindex="5";
                }else if(value>=boundaryrange*-1&&value<0.0){
                    colorindex="4";
                }else if(value==0.0){
                    colorindex="3";
                }else if(value>0.0&&value<=boundaryrange){
                    colorindex="2";
                }else if(value>boundaryrange&&value<=boundary){
                    colorindex="1";
                }else if(value>boundary){
                    colorindex="0";
                }
                break;
            default:
                break
        }
        return colorindex;
	},
	_toDecimal:function(data){
		return data.toFixed(this.profile.decimal);
	},
	updateData:function(gKey,data){

	},
    showRange: function(){
       this.colorGroupObj.showRange({label:this.profile.label,scope:this.profile.scope});
    },
    showMain:function(){
    	QS_MSStyleBoxDataManager.showMain(this.category);
    },
    reSize: function(w, h){
		var parent = this.container;
		var w = w ||this.profile.width||parent.width();
		var h = w;
		
		var showHeader = this.profile.showHeader;
		if(showHeader){
			w -= 25;
			h -= 20;
		}
		var showRange = this.profile.showRange;
		if(showRange)h+= 20;
		
		this.width = w;
		this.el.find(".msstylebox").css({
			width: this.width,
			height: this.width
		});
		this.el.find(".header-right").css({height:this.width});
		this.el.find(".header-bottom").css({width:this.width});
	}
}

var QS_MSStyleBoxcolorGroup = function(container, profile){
	this.el = null;
	this.container = null;
	this.scope = 20;
	this.label = 'Day';
	this.HTML = '<div class="qs_msstyleboxcolorgroup">' +
		    '<div class="title">Day Return</div>' +
			'<div class="container">' +
				'<div class="color"></div>' +
				'<div class="color"></div>' +
				'<div class="color"></div>' +
				'<div class="color"></div>' +
				'<div class="color"></div>' +
				'<div class="color"></div>' +
				'<div class="color"></div>' +
		    '</div>' +
		'<div class="range">' +
			'<div class="high">+'+this.scope+'%</div>' +
			'<div class="mid">0</div>' +
			'<div class="low">-'+this.scope+'%</div>' +
		'</div>' +
	'</div>';
	this.profile={};
	this.colors = ['#42b442','#79d978','#AAF0AA','#d9d9d9','#ffc7c6','#fe9596','#fe0000'];
	this.init(container, profile);
}

QS_MSStyleBoxcolorGroup.prototype = {
	init:function(container, profile){
		this.el = $(this.HTML);
        this.container = container;
        this.el.appendTo(this.container);
        $.extend(true, this.profile, profile);
		
		var colorContainers = this.el.find('.container .color');
		if(this.profile.colors){
			this.colors = this.profile.colors;
		}
		for (var i = 0, l = colorContainers.length; i < l; i++) {
			colorContainers[i].style.backgroundColor = this.colors[i];
		}
	},
	getColors:function(){
		return this.colors;
	},
	showRange:function(profile){
		if(profile.scope){
			this.scope = profile.scope;
		}
		if (profile.label) {
			this.label =profile.label;
		}
		this.el.find('.range .high').html('+'+profile.scope+'%');
		this.el.find('.range .low').html('-'+profile.scope+'%');
		this.el.find('.title').html(this.label+' Return');
	}
}
